package field

import (
	"bytes"
	"database/sql/driver"
	"errors"
	"fmt"
	"strconv"
)

type Point struct {
	Lng float64 `json:"lng"` //经度
	Lat float64 `json:"lat"` //纬度
}

func PointFromBytes(s []byte) (_ Point, err error) {
	p := Point{}
	if len(s) == 0 {
		return p, errors.New("empty point data")
	}
	arr := bytes.SplitN(s, []byte{' '}, 2)
	p.Lat, err = strconv.ParseFloat(string(arr[0]), 64)
	if err != nil {
		return
	}
	p.Lng, err = strconv.ParseFloat(string(arr[1]), 64)
	if err != nil {
		return
	}
	return p, nil
}

func (p Point) Valid() bool {
	return !(p.Lat == 0 && p.Lng == 0)
}

// Value implements sql/driver.Valuer interface.
func (p Point) Value() (driver.Value, error) {
	return fmt.Sprintf("%f %f", p.Lat, p.Lng), nil
}

// Scan implements sql.Scanner interface.
func (p *Point) Scan(value interface{}) (err error) {
	if v, ok := value.([]byte); ok {
		*p, _ = PointFromBytes(v)
		return
	}
	if v, ok := value.(string); ok {
		*p, _ = PointFromBytes([]byte(v))
		return
	}
	return fmt.Errorf("unable to scan %T into Point", value)
}

type NullPoint struct {
	Point Point
	Valid bool // Valid is true if UUID is not NULL
}

// Value implements sql/driver.Valuer interface.
func (n NullPoint) Value() (driver.Value, error) {
	if !n.Valid {
		return nil, nil
	}
	return n.Point.Value()
}

// Scan implements sql.Scanner interface.
func (n *NullPoint) Scan(value interface{}) error {
	if value == nil {
		n.Point, n.Valid = Point{}, false
		return nil
	}
	n.Valid = true
	return n.Point.Scan(value)
}
